package com.appointment.pay.rest.service.impl;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;
import com.appointment.pay.core.entity.OrderInfo;
import com.appointment.pay.core.enums.TradeStateEnum;
import com.appointment.pay.core.mapper.OrderInfoMapper;
import com.appointment.pay.rest.enums.ErrEnum;
import com.appointment.pay.rest.exception.PayException;
import com.appointment.pay.rest.util.AlipayConfig;
import com.appointment.pay.rest.util.AlipayCore;
import com.appointment.pay.rest.util.AlipayNotify;
import com.appointment.pay.rest.util.AlipaySubmit;
import com.appointment.pay.rest.util.UtilDate;
import com.appointment.pay.service.IAlipayService;
import com.appointment.pay.vo.AlipayRequestVo;
import com.appointment.pay.vo.AlipayResponseVo;

/**
 * 支付宝支付dubbo接口实现
 * @author zhul
 *
 */
@Service
public class AlipayServiceImpl implements IAlipayService {
    
    private static Logger logger = LoggerFactory.getLogger(AlipayServiceImpl.class);
    
    @Autowired
    @Value("${alipay.privateKey}")
    private String privateKey;//商户私钥
    
    @Autowired
    @Value("${alipay.publicKey}")
    private String alipayPublicKey;//支付宝公钥
    
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    
    @Override
    public AlipayResponseVo precreate(AlipayRequestVo request) {
        logger.info("支付宝预下单dubbo接口begin...");
        String app_id = request.getApp_id();
        Integer userId = request.getUserId();
        if(StringUtils.isEmpty(app_id)){
            throw new PayException(ErrEnum.ERR11.getMsg(),ErrEnum.ERR11.getCode());
        }
        if(userId == null || userId.intValue() <= 0){
            throw new PayException(ErrEnum.ERR08.getMsg(),ErrEnum.ERR08.getCode());
        }
        String method = AlipayConfig.alipay_precreate_method;
        String charset = AlipayConfig.input_charset;
        String sign_type = AlipayConfig.sign_type;
        String notify_url = AlipayConfig.notify_url;
        String timestamp = UtilDate.getDateFormatter();
        String version = "1.0";
        String biz_content = request.getBiz_content();
        if(StringUtils.isEmpty(biz_content)){
            throw new PayException(ErrEnum.ERR10.getMsg(),ErrEnum.ERR10.getCode());
        }
        logger.info("请求参数：app_id="+", biz_content="+biz_content);
        Map<String, String> sPara = new HashMap<String, String>();
        sPara.put("app_id", app_id);
        sPara.put("method", method);
        sPara.put("charset", charset);
        sPara.put("sign_type", sign_type);
        sPara.put("notify_url", notify_url);
        sPara.put("timestamp", timestamp);
        sPara.put("version", version);
        sPara.put("biz_content", biz_content);
        String sign = AlipaySubmit.buildRequestMysign(sPara, privateKey);
        sPara.put("sign", sign);
        //保存预订单到db
        createAlipayOrderInfo(sPara,userId);
        
        try{
            String postData = AlipayCore.createLinkString(sPara);//请求支付宝接口的参数
            HttpClient client = new DefaultHttpClient();  
            HttpPost post = new HttpPost(AlipayConfig.alipay_url);  
            StringEntity entity = new StringEntity(postData,AlipayConfig.APPLICATION_FORM_URLENCODED);          
            post.setEntity(entity);  

            HttpResponse response = client.execute(post);  
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
                InputStream is = response.getEntity().getContent();  
                String result = AlipaySubmit.inStream2String(is);  
                logger.info("支付宝预下单接口返回result="+result);
                JSONObject resultJson = JSONObject.fromObject(result);
                if(resultJson != null){
                    //1，验签
                    String responseStr = resultJson.getString("alipay_trade_precreate_response");
                    String resultSign = resultJson.getString("sign");
                    Map<String, String> params = new HashMap<String, String>();
                    params.put("alipay_trade_precreate_response", responseStr);
                    if(AlipayNotify.getSignVeryfy(params,resultSign,alipayPublicKey)){
                        //签名通过
                        JSONObject responseJson = resultJson.getJSONObject("alipay_trade_precreate_response");
                        String code = responseJson.getString("code");//结果码
                        String msg = responseJson.getString("msg");//结果码描述
                        if("10000".equalsIgnoreCase(code)){
                            String out_trade_no = responseJson.getString("out_trade_no");//商户订单号
                            String qr_code = responseJson.getString("qr_code");//二维码码串
                            //1.保存二维码到db
                            OrderInfo orderInfo = orderInfoMapper.queryByOutTradeNo(out_trade_no);
                            orderInfo.setQrCode(qr_code);
                            orderInfoMapper.updateOrderInfo(orderInfo);
                            
                            AlipayResponseVo vo = new AlipayResponseVo();
                            vo.setOut_trade_no(out_trade_no);
                            vo.setQr_code(qr_code);
                            return vo;
                        }else{
                            logger.error("支付宝预下单接口请求失败，code="+code+", msg="+msg);
                        }
                    }else{
                        //签名失败
                        logger.error("支付宝预下单接口返回结果签名不正确!");
                    }
                    
                }
            }  
        }catch(Exception ex){
            logger.error("请求支付宝预下单接口异常!",ex);
        }
        
        return null;
    }
    
    /**
     * 保存支付下单记录到db
     * @param sPara
     * @param userId
     */
    private void createAlipayOrderInfo(Map<String, String> sPara,Integer userId){
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setMethod(sPara.get("method"));
        String biz_content = sPara.get("biz_content");
        JSONObject contentJson = JSONObject.fromObject(biz_content);
        String out_trade_no = contentJson.getString("out_trade_no");//商户订单号
        orderInfo.setOutTradeNo(out_trade_no);
        BigDecimal totalAmount = (BigDecimal)contentJson.get("total_amount");//订单总金额，单位为元
        orderInfo.setTotalAmount(totalAmount);
        if(contentJson.containsKey("discountable_amount")){
            BigDecimal discountableAmount = (BigDecimal)contentJson.get("discountable_amount");//可打折金额，单位为元
            orderInfo.setDiscountableAmount(discountableAmount);
        }
        if(contentJson.containsKey("undiscountable_amount")){
            BigDecimal undiscountableAmount = (BigDecimal)contentJson.get("undiscountable_amount");//不可打折金额，单位为元
            orderInfo.setUndiscountableAmount(undiscountableAmount);
        }
        String subject = contentJson.getString("subject");//订单标题
        orderInfo.setSubject(subject);
        if(contentJson.containsKey("body")){
            String body = contentJson.getString("body");//对交易或商品的描述
            orderInfo.setBody(body);
        }
        if(contentJson.containsKey("operator_id")){
            String operatorId = contentJson.getString("operator_id");//商户操作员编号
            orderInfo.setOperatorId(operatorId);
        }
        if(contentJson.containsKey("store_id")){
            String storeId = contentJson.getString("store_id");//商户门店编号
            orderInfo.setStoreId(storeId);
        }
        if(contentJson.containsKey("timeout_express")){
            String timeoutExpress = contentJson.getString("timeout_express");//该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d
            orderInfo.setTimeoutExpress(timeoutExpress);
        }
        orderInfo.setTradeStatus(TradeStateEnum.NOTPAY.getCode());//未支付
        orderInfo.setTradeStatusInfo(TradeStateEnum.NOTPAY.getMessage());
        orderInfo.setCreateTime(new Date());
        orderInfo.setProductCode("BARCODE_PAY_OFFLINE");//条码支付
        
        orderInfoMapper.insertOrderInfo(orderInfo);
    }
}
